﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Remote_server
{
    /// <summary>
    /// Enumeration that describes
    /// different commands
    /// </summary>
    public enum Commands
    {
        FileManager = 0,
        Write,
        Media,
        Volume,
        ScreenShot
    }

    /// <summary>
    /// Contains a Name and the Parameters passed
    /// by the other host
    /// </summary>
    public struct Command
    {
        /// <summary>
        /// The name of the command (eg. "LS", "CD" or "MUTE"
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// Parameters passed together with the command,
        /// everything written after the name is considered
        /// to be the parameters
        /// </summary>
        public string Parameters { get; set; }

        /// <summary>
        /// Initialize the Command with a string as it should
        /// be passed by the other host.
        /// "LS -a" would construct a Command with the name "LS"
        /// and Parameters "-a"
        /// </summary>
        /// <param name="commandString"></param>
        public Command(string commandString)
            : this()
        {
            Name = GetCmdName(commandString);
            Parameters = GetCmdParameters(Name, commandString);
        }

        /// <summary>
        /// Initialize this Command with a Name and an
        /// explicit parameter string
        /// </summary>
        /// <param name="name">The name of this Command</param>
        /// <param name="parameters">The parameter section of the command</param>
        public Command(string name, string parameters)
            : this()
        {
            Name = name;
            Parameters = parameters;
        }

        /// <summary>
        /// Get a string representation of this
        /// Command, formatted as it should be when
        /// passing it using an RspClient
        /// </summary>
        /// <returns>A string representation of this Command</returns>
        public override string ToString()
        {
            return String.Format("{0}{1}", Name, Parameters == "" ? "" : ": " + Parameters);
        }

        /// <summary>
        /// Extracts the Command name from a string
        /// correctly formatted
        /// </summary>
        /// <param name="fullCommand">The string to extract
        /// the name from</param>
        /// <returns>The retreived name</returns>
        private string GetCmdName(string fullCommand)
        {
            int index = fullCommand.IndexOf(' ');

            return index == -1 ? fullCommand.Substring(0) : fullCommand.Substring(0, index);
        }

        /// <summary>
        /// Extract the parameters passed with a command
        /// </summary>
        /// <param name="commandName">The command name</param>
        /// <param name="fullCommand">The full command string</param>
        /// <returns>The retreived parameter part of the command</returns>
        private string GetCmdParameters(string commandName, string fullCommand)
        {
            return commandName.Length > fullCommand.Length ? "" : fullCommand.Substring(commandName.Length);
        }
    }

    /// <summary>
    /// Contains an internal table with command
    /// names associated to a specific value from the
    /// Commands enumeration
    /// </summary>
    public static class CommandStrings
    {
        //The commands are retreived by converting
        //a value from the Commands enum to an integer index
        private static readonly string[][] cmds = new string[][]
        {
            new string[]{"LS", "CD", "GET"},
            new string[]{"RM"},
            new string[]{"PLAY", "PAUSE", "STOP", "NEXT", "PREV"},
            new string[]{"VOLUP", "VOLDOWN", "MUTE"},
            new string[]{"SCREEN"}
        };

        /// <summary>
        /// Retreive the Command names associated
        /// with a specific value from the Commands
        /// enumeration
        /// </summary>
        /// <param name="command">A value from the Commands enum</param>
        /// <returns>The strings associated with the value</returns>
        public static string[] S(Commands command)
        {
            return cmds[(int)command];
        }
    }
}
